const { spawn } = require("child_process");
const Sftp = require("../tools/sftp");
const command = require("../tools/command");
const utils = require("../utils");
const qw = require("../tools/qw");
const qr = require("../tools/qr");
const remoteConfig = require("./../config/server");
const nodepath = require("path");
const DeployModel = require("../models/deploy");
const ProjectModel = require("../models/project");
const Joi = require("joi");
const ci = require("miniprogram-ci"); // 引入ci
const { setLocalsState, sendResult } = require("../handler");
const path = require("path");
const BASE_URL = "d:/publicworks/";

const joinFullPath = (projectName) => {
  return `${BASE_URL}${projectName}`;
};

module.exports.sendToGroup = async () => {
  const fullpath = joinFullPath("yoga-sass");
  process.chdir(fullpath);
  await command.exec(["pnpm build", "pnpm tar"]);
  const folder = nodepath.resolve(fullpath, "archive");
  const [filepath] = utils.traverseFolder(folder);
  await qw.sendFileToWeChatGroup(filepath);
  qw.sendTextToEnterpriseWeChatGroup("发包完成");
};

// 之前固定写死的
module.exports.deploy = async (req, res, next) => {
  const schema = Joi.object({
    desc: Joi.string().min(8).max(500),
  });
  try {
    const result = schema.validate(req.body);
    if (result.error) {
      throw new Error(result.error.details[0].message);
    }
    const fullpath = joinFullPath("yoga-sass");
    process.chdir(fullpath);
    await command.exec(["pnpm tar"]);
    const fileFolder = BASE_URL + `yoga-sass/archive`;
    const [filepath = ""] = utils.traverseFolder(fileFolder);
    const [fileName = ""] = filepath.split("\\").slice(-1);
    const sftp = new Sftp();
    await sftp.uploadDir(remoteConfig, fileFolder);
    await sftp.rmdir(remoteConfig, remoteConfig.path + "/dist");
    await sftp.untargz(remoteConfig, fileName);
    sftp.close();
    qw.sendTextToEnterpriseWeChatGroup(
      ` nginx 正式环境发布完成
          ${result?.value?.desc}
      `
    );
    const doc = await new DeployModel({
      user: req.userToken.oId,
      ...result.value,
    }).save();

    if (doc) {
      next();
    }
  } catch (e) {
    next(e);
  }
};

module.exports.backend = async (req, res, next) => {
  const schema = Joi.object({
    id: Joi.string().required(),
    desc: Joi.string().min(8).max(500),
  });
  try {
    const result = schema.validate(req.body, {
      abortEarly: false,
      allowUnknown: true,
    });
    if (result.error) {
      throw new Error(result.error.details[0].message);
    }
    //  1 是关， 0是开
    const projectDoc = await ProjectModel.findById(result.value.id).populate(
      "user form"
    );
    if (!projectDoc) {
      throw new Error("没有查询到项目");
    }
    const projectJSON = projectDoc.toJSON();
    const serverSchema = Joi.object({
      projectName: Joi.string().required().error(new Error("缺少项目名称")),
      archive: Joi.string().required().error(new Error("缺少存档路径")),
      host: Joi.string().required().error(new Error("缺少host地址")),
      username: Joi.string().required().error(new Error("缺少服务器用户名")),
      path: Joi.string().required().error(new Error("缺少服务器路径")),
      port: Joi.string().required().error(new Error("缺少服务器端口")),
      password: Joi.string().required().error(new Error("缺少服务器密码")),
    });
    const serveValid = serverSchema.validate(projectJSON.formFieldsValue, {
      abortEarly: false,
      allowUnknown: true,
    });
    if (serveValid.error) {
      throw new Error(serveValid.error.details[0].message);
    }
    const fullpath = joinFullPath(serveValid.value.projectName);
    process.chdir(fullpath);
    console.log("正在开始打包...");
    await command.exec(["pnpm tar"]);
    console.log("打包完成准备上传...");
    const fileFolder =
      BASE_URL + `${serveValid.value.projectName}/${serveValid.value.archive}`;
    const [filepath = ""] = utils.traverseFolder(fileFolder);
    const [fileName = ""] = filepath.split("\\").slice(-1);
    const sftp = new Sftp();
    const remoteConfig = {
      host: serveValid.value.host,
      username: serveValid.value.username,
      path: serveValid.value.path,
      port: serveValid.value.port,
      password: serveValid.value.password,
    };
    await sftp.uploadDir(remoteConfig, fileFolder);
    await sftp.rmdir(remoteConfig, remoteConfig.path + "/dist");
    await sftp.untargz(remoteConfig, fileName);
    sftp.close();
    qw.sendTextToEnterpriseWeChatGroup(
      ` nginx 正式环境发布完成
          ${result?.value?.desc}
      `
    );
    const doc = await new DeployModel({
      user: req.userToken.oId,
      ...result.value,
    }).save();

    if (doc) {
      next();
    }
  } catch (e) {
    next(e);
  }
};

module.exports.wxApplet = async (req, res, next) => {
  if (!req.body.id) {
    throw new Error("缺少项目ID");
  }
  try {
    const projectDoc = await ProjectModel.findById(req.body.id).populate(
      "user form"
    );
    if (!projectDoc) {
      throw new Error("没有查询到项目");
    }
    const joiSchema = Joi.object({
      env: Joi.string().required().error(new Error("缺少小程序接口环境")),
      appid: Joi.string().required().error(new Error("缺少小程序appid")),
      projectPath: Joi.string()
        .required()
        .error(new Error("缺少小程序dist路径")),
      privateKeyPath: Joi.string().required().error(new Error("缺少key路径")),
      dist: Joi.string().required().error(new Error("缺少dist路径")),
    });
    const { formFieldsValue, name, isNotifi } = projectDoc.toJSON();
    const serveValid = joiSchema.validate(formFieldsValue, {
      abortEarly: false,
      allowUnknown: true,
    });

    if (serveValid.error) {
      throw new Error(serveValid.error.details[0].message);
    }
    const { appid, projectPath, privateKeyPath, env, dist } = serveValid.value;
    process.chdir(projectPath);
    await command.spawnExec("yarn.cmd", ["env", env], {
      shell: true,
    });
    await command.spawnExec("yarn.cmd", ["build"], { shell: true });
    const outputPath = path.join(__dirname, "..", "dest", `${appid}.jpg`);
    const project = new ci.Project({
      appid,
      type: "miniProgram",
      projectPath: dist,
      ignores: ["node_modules/**/*"],
      privateKeyPath: `${privateKeyPath}\\private.${appid}.key`,
    });

    const nextVersion = await ProjectModel.incrementNumber(projectDoc);
    await ci.upload({
      project,
      version: nextVersion,
      desc: "测试自动化构建",
      setting: {
        minify: true, // 上传时压缩所有代码，对应于微信开发者工具的 "上传时压缩代码"
        es6: true, // 对应于微信开发者工具的 "es6 转 es5"
        autoPrefixWXSS: true,
      },
      robot: 1,
      onProgressUpdate: console.log, // 进度更新监听函数
    });
    const previewResult = await ci.preview({
      project,
      desc: 'hello', // 此备注将显示在“小程序助手”开发版列表中
      setting: {
        es6: true,
      },
      qrcodeFormat: 'image',
      qrcodeOutputDest: outputPath,
      onProgressUpdate: console.log,
    });
    
    const doc = await new DeployModel({
      user: req.userToken.oId,
      desc: req.body?.desc || "版本发布"
    }).save();
    if (isNotifi) {
      qw.sendTextToEnterpriseWeChatGroup(
        ` 微信小程序 体验版发布完成(测试中)
          项目名称: ${name}
          appId: ${appid}
          接口环境: ${env}
  
          发布描述： ${req.body.desc}
        `
      );
      qw.sendImgToEnterpriseWeChatGroup(outputPath);
    }
    next();
  } catch (e) {
    console.log(e.stack, e.message);
    next(e);
  }
};

// 0 是关 1是开
module.exports.switchNotifi = async(req, res, next) => {

  try {
    if (!req.body.id) {
      throw new Error("缺少项目ID");
    }
    const projectDoc = await ProjectModel.findById(req.body.id).populate(
      "user form"
    );
    if (!projectDoc) {
      throw new Error("没有查询到项目");
    }
    projectDoc.isNotifi = req.body.isNotifi;
    await projectDoc.save();
    sendResult(res, true, 'ok');
  } catch(e) {
    sendResult(res, e, 'err');
  }
}

module.exports.record = async (req, res, next) => {
  try {
    const data = await DeployModel.paginate({});
    setLocalsState(res, { deployRecord: data });
    next();
  } catch (e) {
    next(e);
  }
};
